/*
Application Clerk
*/
#define APPLINE 1
#define PICLINE 2
#define PASLINE 3
#define CASHIER 4
#define CUSTOMER 5
#include "syscall.h"


int myexp ( int count ) {
  int i, val=1;
  for (i=0; i<count; i++ ) {
    val = val * 10;
  }
  return val;
}

void itoa( char arr[], int size, int val ) {
  int i, max, dig, subval, loc;
  for (i=0; i<size; i++ ) {
    arr[i] = '\0';
  }

  for ( i=1; i<=2; i++ ) {
    if (( val / myexp(i) ) == 0 ) {
      max = i-1;
      break;
    }
  }

  subval = 0;
  loc = 0;
  for ( i=max; i>=0; i-- ) {
    dig = 48 + ((val-subval) / myexp(i));
    subval = (dig-48) * myexp(max);
    arr[loc] = dig;
    loc++;
  }

  return;
}


void concatenate(char buf[], char arr1[], int len1, char arr2[], int len2){
	
	int i;

	for(i = 0; i<len1+len2; i++){
		if(i<len1){
			buf[i] = arr1[i];
		}
	  
		else if(i - len1 < len2){
			buf[i] = arr2[i - len1];
		}
		else buf[i] = '!';
	}
	
}

void ApplicationClerk()
{

	char buf[256];
	char buf1[256];
	char buf2[256];
	char name[16];
	char cusname[4];
	int index;
	int cust;


  index = RegisterMe(APPLINE);
  itoa(&name[11],4,index);
  name[0] = 'A'; name[1] = 'P'; name[2] = 'P'; name[3] = '_'; 
  name[4] = 'C'; name[5] = 'L'; name[6] = 'E'; name[7] = 'R';
  name[8] = 'K'; name[9] = ' '; name[10]= '#'; name[15] = '\0';

  concatenate(buf,name,16,": Application Clerk Process created and currently running\n", 58);
  Write(buf,16+58,ConsoleOutput);

  while(1){

	  concatenate(buf,name,16,": Ready to serve next customer, now waiting for customer\n", 57);
	  Write(buf,16+57,ConsoleOutput);



	  cust = RemoveCustomer(index, APPLINE);    
	  itoa(cusname, 4, cust);



	  concatenate(buf1,name,16,": Serving customer #", 20);
	  concatenate(buf2,cusname,4,", received his application\n",27);
	  concatenate(buf,buf1,16+20,buf2,4+27);
	  Write(buf,16+20+4+27,ConsoleOutput);

	  /*
	  Write(name,16,ConsoleOutput);
	  Write(": Serving customer #", 20, ConsoleOutput);
	  
	  Write(cusname, 4, ConsoleOutput);
	  Write(", received his application\n", 27, ConsoleOutput);
   /*                1         2         3         4         5         6         7         8         9         10*/
   /*       1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 */


  }
}


void main(){

  /*
    Run Application Clerk
  */

  ApplicationClerk();


}






  /*
  int myIndex = nextAppClerkIndex;
  /*int fileTime = (rand()%80) + 20;
  //int fileTime = 70;
  int a,b;

  Print("Application Clerk Process  is made and currently running\n");


  nextAppClerkIndex++;
  appClerkDesk[myIndex];
  //initialize values
  appClerkDesk[myIndex].waitingLine_Lock = CreateLock();
  appClerkDesk[myIndex].waitingApp_Condition = CreateCondition();
  appClerkDesk[myIndex].goingOnBreak_Lock = CreateLock();
  appClerkDesk[myIndex].wakeUp_Condition = CreateCondition();
 
  AcquireLock(appClerkDesk[myIndex].waitingLine_Lock);
 


  appClerkDesk[myIndex].money = 0;
  appClerkDesk[myIndex].state = Ready;
  appClerkDesk[myIndex].SSN = 500;
  appClerkDesk[myIndex].customerAtDesk = false;
  appClerkDesk[myIndex].isOccupied = true;
  
  Print("appClerkDesk initialized\n");
 
  ReleaseLock(appClerkDesk[myIndex].waitingLine_Lock);
 
  
  while(true){
    /*main waiting on customers loop
    AcquireLock(senator.active_Lock);
    if(senator.state == acknowledged  || senator.state == active){
      ReleaseLock(senator.active_Lock);
      Print("Application Clerk: Senator here, emptying out liens\n");
      while(appClerkLine.lineLength > 0){
	removeCustomer(&appClerkLine);
      }
      while(preferred_appClerkLine.lineLength > 0){
	removeCustomer(&preferred_appClerkLine);
      }
      /*Signal and wait for senator
      Print("Application Clerk: emptied lines, waiting for senator\n");
      AcquireLock(appClerkDesk[myIndex].waitingLine_Lock);
      appClerkDesk[myIndex].state = WaitingOnCustomer;

      if(myIndex == 0){
	SignalCondition(senator.waiting_Condition,senator.active_Lock);
      }
      WaitCondition(appClerkDesk[myIndex].waitingApp_Condition,appClerkDesk[myIndex].waitingLine_Lock);
      
      /*Interaction with senator
      if(appClerkDesk[myIndex].customerAtDesk)
	{
	  Print("Application Clerk: Interacting with senator\n");
	  appClerkDesk[myIndex].customerAtDesk = false;
	  Print("Application Clerk: Senator application filed, interaction finsihed\n");
	  SignalCondition(appClerkDesk[myIndex].waitingApp_Condition,appClerkDesk[myIndex].waitingLine_Lock);
	  WaitCondition(appClerkDesk[myIndex].waitingApp_Condition,appClerkDesk[myIndex].waitingLine_Lock);
	}
      ReleaseLock(appClerkDesk[myIndex].waitingLine_Lock);
      
      /*Signaled that the senator is gone, clerk is ready again
      appClerkDesk[myIndex].state = Ready;
      Print("Application Clerk: senator is gone, I am ready to serve customer again\n");
      /*continue onto the next loop

    }
    else ReleaseLock(senator.active_Lock);
    
    /*Serve the customers
    AcquireLock(appClerkDesk[myIndex].waitingLine_Lock);
    /*no customers in the line
    if((appClerkLine.lineLength == 0) && (preferred_appClerkLine.lineLength == 0)){
      ReleaseLock(appClerkDesk[myIndex].waitingLine_Lock);
      
      /*go on break
      Print("Application Clerk: Line empty going on break\n");
      AcquireLock(appClerkDesk[myIndex].goingOnBreak_Lock);
      appClerkDesk[myIndex].state = OnBreak;
      appClerkDesk[myIndex].isOccupied = false;
      WaitCondition(appClerkDesk[myIndex].wakeUp_Condition, appClerkDesk[myIndex].goingOnBreak_Lock);
      
      /*woekn up, ready to serve again
      appClerkDesk[myIndex].state = Ready;
      ReleaseLock(appClerkDesk[myIndex].goingOnBreak_Lock);
      Print("Application Clerk: OK, i'm back from break, ready to serve customers\n");
    }
    /*Check if there is anyone in preferred_appClerkLine.  if there is someone serve him.
    else if(!appClerkDesk[myIndex].customerAtDesk && 
	    preferred_appClerkLine.lineLength > 0 &&
	    appClerkDesk[myIndex].state == Ready)
      {
	Print("Application Clerk: waiting for preferred customers\n");
	/*preferred customer must pay 500.
	appClerkDesk[myIndex].money += 500;
	Print("Application Clerk: Preferred customer paid\n");
	removeCustomer(&preferred_appClerkLine);
	appClerkDesk[myIndex].state = WaitingOnCustomer;
	/*wait for customer to come to desk, does not have to be signaled customer
	WaitCondition(appClerkDesk[myIndex].waitingApp_Condition, appClerkDesk[myIndex].waitingLine_Lock);
	
	/*if first customer from line picks this clerk
	if(appClerkDesk[myIndex].customerAtDesk){
	  Print("Application Clerk: interacting with customer\n");
	  appClerkDesk[myIndex].customerAtDesk = false;
	  Print("Application Clerk: Customer interaction finished\n");
	  /*wake current customer back up
	  SignalCondition(appClerkDesk[myIndex].waitingApp_Condition, appClerkDesk[myIndex].waitingLine_Lock);
	  
	  /*FILE CODE:
	  for(a=0;a<fileTime;a++){
	    Yield();
	  }
	  /*find available slot to file ssn
	  for(b=0;b<5;b++){
	    AcquireLock(appOK_Lock);	

	    if(appOK[b] == 500)
	      {
		appOK[b] = appClerkDesk[myIndex].SSN;
		  b = 5; /*now exit
	      }

	    ReleaseLock(appOK_Lock);
	  }
	  Print("Application Clerk: after Yielding application filed\n");
	}

	appClerkDesk[myIndex].state = Ready;
	ReleaseLock(appClerkDesk[myIndex].waitingLine_Lock);
      }

    /*Check if there is anyone in regular appClerkLine.  if there is someone serve him.
    else if(!appClerkDesk[myIndex].customerAtDesk && 
	    appClerkLine.lineLength > 0 &&
	    appClerkDesk[myIndex].state == Ready)
      {
	Print("Application Clerk: waiting for regular customers\n");
	
	removeCustomer(&appClerkLine);
	appClerkDesk[myIndex].state = WaitingOnCustomer;
	/*wait for customer to come to desk, does not have to be signaled customer
	WaitCondition(appClerkDesk[myIndex].waitingApp_Condition, appClerkDesk[myIndex].waitingLine_Lock);
	
	/*if first customer from line picks this clerk
	if(appClerkDesk[myIndex].customerAtDesk){
	  Print("Application Clerk: interacting with customer\n");
	  appClerkDesk[myIndex].customerAtDesk = false;
	  Print("Application Clerk: Customer interaction finished\n");
	  /*wake current customer back up
	  SignalCondition(appClerkDesk[myIndex].waitingApp_Condition, appClerkDesk[myIndex].waitingLine_Lock);
	  
	  /*FILE CODE:
	  for(a=0;a<fileTime;a++){
	    Yield();
	  }
	  /*find available slot to file ssn
	  for(b=0;b<5;b++){
	    AcquireLock(appOK_Lock);	

	    if(appOK[b] == 500)
	      {
		appOK[b] = appClerkDesk[myIndex].SSN;
		  b = 5; /*now exit
	      }

	    ReleaseLock(appOK_Lock);
	  }
	  Print("Application Clerk: after Yielding application filed\n");
	}

	appClerkDesk[myIndex].state = Ready;
	ReleaseLock(appClerkDesk[myIndex].waitingLine_Lock);
      }

    else
      {
	/*check error
	ReleaseLock(appClerkDesk[myIndex].waitingLine_Lock);
	Print("Application Clerk: error application clerk found nothing to do!\n");
      }

	
  }


}

      */
